package cn.easy.mortgage.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
import cn.easy.base.bean.PageBean;
import cn.easy.base.domain.User;
import cn.easy.base.service.BaseService;
import cn.easy.base.service.ConfigService;
import cn.easy.base.service.UserService;
import cn.easy.base.utils.BaseUtils;
import cn.easy.base.utils.ExtractUtil;
import cn.easy.base.utils.Global;
import cn.easy.mortgage.domain.Channel;
import cn.easy.mortgage.repository.ChannelDao;
import cn.easy.mortgage.utils.Constants;
import cn.easy.mortgage.zxing.ZXingCode;
import cn.easy.weixin.utils.QrCodeUtils;
import com.google.common.collect.Lists;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.utils.io.FilePathUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@Component
public class ChannelService extends BaseService<Channel> {
    @Autowired
    private ChannelDao channelDao;
    @Autowired
    private UserService userService;
    @Autowired
    private ConfigService configService;

    public Page<Channel> search(Map<String, Object> searchParams, PageBean pageBean) {
        return channelDao.findAll(spec(searchParams), pageBean.toPageRequest(new Sort(Direction.ASC, "no")));
    }

    public List<Channel> search(Map<String, Object> searchParams, Sort... sort) {
        return channelDao.findAll(spec(searchParams), sort == null || sort.length == 0 ? new Sort(Direction.DESC, "createdAt") : sort[0]);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void delete(String id) {
        channelDao.delete(id);
    }

    public Channel getOne(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        return channelDao.findOne(id);
    }

    public List<Channel> findAll(List<String> idList) {
        return Lists.newArrayList(channelDao.findAll(idList));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Channel save(Channel channel) {
        return channelDao.save(channel);
    }

    public Channel findByCode(String code) {
        return channelDao.findByCode(code);
    }

    public Channel findByUserId(String userId){
        return channelDao.findByUserId(userId);
    }

    public User valueOf(Channel channel) {
        User user = new User();
        user.setUsername(channel.getCode());
        user.setRealname(channel.getName());
        user.setOrganId("00000000000000000000000000000001");
        user.setPassword(BaseUtils.encodePassword(cn.easy.base.utils.Constants.DEFAULT_PASSWORD));
        user.setMobile(channel.getMobile());
        return user;
    }

    public String genQrCode(Channel channel, String type, HttpServletRequest request) throws IOException, WxErrorException {
        String defaultRoot = configService.getConfigValue(Global.FILE_UPLOAD_DIR_KEY);
        String qrCodeDir = FilePathUtil.contact(defaultRoot, "qrCode");
        if (!new File(qrCodeDir).exists()) {
            new File(qrCodeDir).mkdirs();
        }

        if ("H5".equalsIgnoreCase(type)) {
//            return genH5QrCode(channel, qrCodeDir, request);
            return genH5ZXingCode(channel, qrCodeDir, request);
        }
        return genMaQrCode(channel, qrCodeDir);
    }

    public String genH5ZXingCode(Channel channel, String qrCodeDir, HttpServletRequest request) throws IOException {
        String qrCodePath = FilePathUtil.contact(qrCodeDir, channel.getId() + "_qrCode.png");
        String url = request.getScheme() + "://" + request.getServerName() + (String.valueOf(request.getServerPort()).equals("80") ? "" : ":" + request.getServerPort())
                + "/app/mp/mtg?" + Constants.CHANNEL_CODE + "=" + channel.getCode();
        ZXingCode.encoderZXCode(url, qrCodePath, 420, 420);
        String resultPath = mergeImg(channel, qrCodeDir, new File(qrCodePath));
        return resultPath;
    }

    public String genMaQrCode(Channel channel, String qrCodeDir) throws WxErrorException, IOException {
        WxMaInMemoryConfig wxMaConfig = new WxMaInMemoryConfig();
        wxMaConfig.setAppid("wx5e9edfdf0a7831a3");
        wxMaConfig.setSecret("a05403dbd419b2268ffa7997d588dc5d");
        wxMaConfig.setAesKey("123456");

        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(wxMaConfig);

        File qrCodeFile = wxMaService.getQrcodeService().createWxaCodeUnlimit("channel#" + channel.getCode(), null, 420, true, null, false);

        String resultPath = mergeImg(channel, qrCodeDir, qrCodeFile);

        return resultPath;
    }

    public String mergeImg(Channel channel, String qrCodeDir, File qrCodeFile) throws IOException {
        String resultPath = FilePathUtil.contact(qrCodeDir, channel.getId() + ".png");
        PathMatchingResourcePatternResolver loader = new PathMatchingResourcePatternResolver();
        Resource resource = loader.getResource("classpath:static/img/qrCode.png");
        File bgImg = resource.getFile();

        QrCodeUtils.addImage2Pic(107, 300, qrCodeFile.getPath(), bgImg.getPath(), resultPath);

        return resultPath;
    }

    public List<Channel> findByType(int type){
        return channelDao.findByType(type);
    }

    public List<String> getUserListByType(int type){
        List<Channel> channelList = findByType(type);
        return ExtractUtil.extractToList(channelList, "userId");
    }

    public List<Channel> findByPid(String pid){
        return channelDao.findByPid(pid);
    }

    public List<Channel> findByNoStartingWith(String no) {
        return channelDao.findByNoStartingWith(no);
    }

    public List<Channel> findByNo(String no){
        return channelDao.findByNo(no);
    }
}


